/*
 * Android Simple Music player
   Copyright hayoon.ko (shauku@naver.com)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package kr.ac.kaist.simplemusicplayer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.ConnectivityManager;
import android.os.DeadObjectException;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

/**
 * SimpleMusicPlayer Service 
 * 1. listen Power connection event with Broadcast receiver and pause music if music is playing
 * 2. receive msg from MusicControl & MusicList and to the actual music-related operations 
 * 3. run in background and keep playing music
 * @author shauku@naver.com
 * @version 10
 *
 */

public class SMPService extends Service {

	private MediaPlayer m_player = new MediaPlayer();
	private List<String> song_path_list = new ArrayList<String>();
	private List<String> id_list = new ArrayList<String>();
	private List<String> title_list = new ArrayList<String>();
	private int currentPosition;
	private boolean isPaused = false;
	private boolean isStopped = true;
	
	private NotificationManager noti_mgr;
	private static final int NOTI_ID = R.layout.activity_music_list;
	
	private BroadcastReceiver mReceiver = null;

	
	public IBinder getBinder(){
		return mBinder;
	}
	
	public IBinder onBind(Intent arg0){
		Log.d("bound", "bound");
		return mBinder;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		noti_mgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

		/**
		  * create intent filter and add event which will be heard
		  */		
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_BATTERY_CHANGED);
		filter.addAction(Intent.ACTION_BATTERY_LOW);
		filter.addAction(Intent.ACTION_BATTERY_OKAY);
		filter.addAction(Intent.ACTION_POWER_CONNECTED);
		filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
		

		/**
		  * create broadcastreceiver and register it with filter above
		  */		
		mReceiver = new BroadcastReceiver(){
		   public void onReceive (Context context, Intent intent){
		      String action = intent.getAction();
		      
		      if (action.equals(Intent.ACTION_BATTERY_CHANGED)){

		      }
		      if(action.equals(Intent.ACTION_BATTERY_LOW)){
		         // To do
		      }
		      if (action.equals(Intent.ACTION_BATTERY_OKAY)){
		         // To do
		      }
		      if (action.equals(Intent.ACTION_POWER_CONNECTED)){
		    	  if((isStopped == false)&&(isPaused == false)){
			    	  Toast.makeText(context, "Power connected. Pausing music", Toast.LENGTH_LONG).show();	
			    	  pauseSong();
		    	  }
		
		      }
		      if (action.equals(Intent.ACTION_POWER_DISCONNECTED)){

		      }
		   }
		};

		this.registerReceiver(this.mReceiver, filter);
	}	
	
	@Override
	public void onDestroy() {
		m_player.stop();
		m_player.release();
		noti_mgr.cancel(NOTI_ID);
		
		unregisterReceiver(mReceiver);
	}	
	
	private final SMPInterface.Stub mBinder = new SMPInterface.Stub(){
		
		
		public void playFile(int position) throws DeadObjectException{
			try{
				currentPosition = position;
				playSong(song_path_list.get(position));
				isStopped = false;
			}catch(IndexOutOfBoundsException e){
				Log.e(getString(R.string.app_name),e.getMessage());
			}
		}
		
		public void addSongPlaylist(String song, String id, String title) throws DeadObjectException {
			song_path_list.add(song);
			id_list.add(id);
			title_list.add(title);
		}
		
		public void clearPlaylist() throws DeadObjectException {
			song_path_list.clear();
			id_list.clear();
			title_list.clear();
		}		
		
		public void skipBack() throws DeadObjectException {
			prevSong();
			isStopped = false;
			isPaused = false;
		}
		
		public void skipForward() throws DeadObjectException {
			nextSong();
			isStopped = false;
			isPaused = false;
		}
		
		public void pause() throws DeadObjectException{
			pauseSong();
		}
		
		public void stop() throws DeadObjectException {
			noti_mgr.cancel(NOTI_ID);
			m_player.stop();
			isStopped = true;
			isPaused = false;
		}
		
		public String getCurrentSongId() {
			return id_list.get(currentPosition);
		}		
		
		public String getCurrentSongTitle(){
			return title_list.get(currentPosition);
		}
		
		public boolean isPlayerStopped(){
			return isStopped;
		}
		
		public boolean isPlayPaused(){
			return isPaused;
		}
	};
	
	private void playSong(String file) {
		try {

			 NotificationCompat.Builder builder = new NotificationCompat.Builder(SMPService.this);
           builder.setSmallIcon(R.drawable.playbackstart)
                      .setContentTitle("SMPlayer")
                      .setContentText("Music started")
                      .setAutoCancel(true);
           noti_mgr.notify(NOTI_ID,builder.build());

			m_player.reset();
			m_player.setDataSource(file);
			m_player.prepare();
			m_player.start();

			m_player.setOnCompletionListener(new OnCompletionListener() {

				public void onCompletion(MediaPlayer arg0) {
					nextSong();
				}
			});

		} catch (IOException e) {
			Log.e(getString(R.string.app_name), e.getMessage());
		}
	}
	
	private void nextSong() {
		// Check if last song or not
		if (++currentPosition >= song_path_list.size()) {
			currentPosition = 0;
			noti_mgr.cancel(NOTI_ID);
		} else {
			playSong(song_path_list.get(currentPosition));
		}
	}	
	
	private void prevSong() {
		if (m_player.getCurrentPosition() < 3000 && currentPosition >= 1) {
			playSong(song_path_list.get(--currentPosition));
		} else {
			playSong(song_path_list.get(currentPosition));
		}
	}	
	
	private void pauseSong(){

		if (isPaused) {
			 NotificationCompat.Builder builder =
                     new NotificationCompat.Builder(SMPService.this);
           builder.setSmallIcon(R.drawable.playbackstart)
                      .setContentTitle("SMPlayer")
                      .setContentText("Music resumed")
                      .setAutoCancel(true);							
           noti_mgr.notify(NOTI_ID,builder.build());
           
           m_player.start();
		
		}else{
			 NotificationCompat.Builder builder =
                     new NotificationCompat.Builder(SMPService.this);
           builder.setSmallIcon(R.drawable.playbackpause)
                      .setContentTitle("SMPlayer")
                      .setContentText("Music paused")
                      .setAutoCancel(true);		
           noti_mgr.notify(NOTI_ID,builder.build());
           
           m_player.pause();
		}
		
		isPaused = !isPaused;			
			
	}
}
